
using System;
using System.Linq;
using System.Reflection;
using log4net;

namespace Karma.Framework.Core.Modules.Reports.Definition.Expression
{
    internal abstract class ExpressionBase: IExpression
    {
        private static readonly ILog LOG = LogManager.GetLogger(typeof(ExpressionBase).Name);

        protected Criteria _criteria;

        private static int _paramCount = 0;

        public ExpressionBase(Criteria criteria)
        {
            _criteria = criteria;
        }

        public abstract CompiledExpression Compile(Report report);

        protected static string GenerateIdentifier()
        {
            return string.Format("parameter{0}", _paramCount++);
        }

        protected string GetIdentifier(Report report)
        {
            var start = report.Query.IndexOf("from ");
            var space = report.Query.IndexOf(' ', start + 1);
            space = report.Query.IndexOf(' ', space + 1);
            return report.Query.Substring(space + 1, 1);
        }

        protected object Cast(string value)
        {
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug(string.Format("Casting [{0}] to type [{1}]", value, _criteria.DataType));
            }
            if (_criteria.DataType.Equals("string"))
            {
			    return value;
		    }
            if (_criteria.DataType.Equals("DateTime"))
            {
			    return DateTime.Parse(value);
		    }
            if (_criteria.DataType.Equals("Int64"))
            {
			    return Int64.Parse(value);
		    }
            if (_criteria.DataType.Equals("Int32"))
            {
			    return Int32.Parse(value);
		    }
            if (_criteria.DataType.Equals("Double"))
            {
                return Double.Parse(value);
            }
            if (_criteria.DataType.Equals("Boolean"))
            {
			    return Boolean.Parse(value);
		    }
            if (_criteria.DataType.IndexOf("Enum") != -1)
            {
                var etype = Type.GetType(_criteria.DataType);
			    return Enum.Parse(etype, value);
		    }

            throw new ArgumentException(string.Format("Tipo no soportado: {0}", _criteria.DataType));
        }
    }
}